package com.centerserver;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultListModel;

class CaptureEndServerThread extends Thread {

	private ServerSocket mServerSocket;
	private DefaultListModel mCaptureEndListModel;
	private DefaultListModel mCaptureVideoItemListModel;
	private DatabaseManager mDatabaseManager;
	private boolean mIsFinished;
	private Map<String, List<String>> mMonitorListMap;
//	private Map<String, InetAddress> mInetAddrMap;

	public CaptureEndServerThread(DefaultListModel captureEndListModel, 
			DefaultListModel captureVideoItemListModel,
			DatabaseManager databaseManager,
			Map<String, List<String>> monitorListMap
			/*,
			Map<String, InetAddress> inetAddrMap*/) {

		mCaptureEndListModel = captureEndListModel;
		mCaptureVideoItemListModel = captureVideoItemListModel;
		mDatabaseManager = databaseManager;
		mMonitorListMap = monitorListMap;
//		mInetAddrMap = inetAddrMap;
		try {
			mServerSocket = new ServerSocket(
					CenterServerConfig.CAPTURE_END_REQUEST_CONNECT_PORT);
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	@Override
	public void run() {

		try {
			mIsFinished = false;

			while (true) {
				boolean isFinished = false;
				synchronized ("mIsFinished") {
					isFinished = mIsFinished;
				}
				if (isFinished)
					break;
				Socket client = mServerSocket.accept();

				// start one session thread to process
				TCPSessionThread tcpSessionThread = new TCPSessionThread(client);
				tcpSessionThread.start();

			}

		} catch (Exception e) {

			System.out.println("Server socket closed");
			// e.printStackTrace();
		} finally {
			try {
				mServerSocket.close();
			} catch (IOException e) {

				System.out.println("Server socket closed");
				e.printStackTrace();
			}
		}

	}

	public void setFinished() {
		synchronized ("mIsFinished") {
			mIsFinished = true;
		}
		try {
			if (null != mServerSocket)
				mServerSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class TCPSessionThread extends Thread {

		private Socket mSocket;
		private InputStream inputStream;
		private String mIpAddress;

		public TCPSessionThread(Socket socket) {
			mSocket = socket;
			mIpAddress = ((InetSocketAddress)mSocket.getRemoteSocketAddress()).getAddress().getHostAddress();
						
			System.out.println(mIpAddress);
		
			try {
				inputStream = mSocket.getInputStream();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		@Override
		public void run() {

			int captureEndNameLen;
			try {
				captureEndNameLen = inputStream.read();

				byte[] captureEndName = new byte[captureEndNameLen];
				inputStream.read(captureEndName, 0, captureEndNameLen);
				
				// add the capture end name to list
				String capName = new String(captureEndName, "ISO-8859-1");
				List<String> ipAddrList = new ArrayList<String>();
				mMonitorListMap.put(capName, ipAddrList);
								
				// indicate that record video thread has started
				if ( !mDatabaseManager.hasAvailableCaptureEnd() ) {
					new RecordVideoThread(
							mDatabaseManager, 
							mCaptureVideoItemListModel,
							mMonitorListMap/*, 
							mInetAddrMap*/).start();
					System.out.println("record video thread started");
				}

				// the current capture end is new, that is, 
				// there is no record in the database
				if (mDatabaseManager.addCaptureEnd(capName, mIpAddress)) {
					mCaptureEndListModel.addElement(capName);
					
					// make one directory under the root directory
					File newFile = new File(
							CenterServerConfig.RECORD_VIDEO_FULL_PATH_ROOT_DIR
									.concat(capName));
					newFile.mkdir();
				}

			} catch (Exception e) {

				e.printStackTrace();
			}
		}

	}

}
